import json
import re

from django import http
from django.contrib.auth import login, authenticate
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.views import logout
from django.db import DatabaseError
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from django_redis import get_redis_connection

from apps.areas.models import Address
from apps.users.models import User
from utils.response_code import RETCODE


class RegisterView(View):
    '''注册'''

    def get(self, request):
        return render(request, 'register.html')

    def post(self, request):

        # 获取参数
        json_dict = json.loads(request.body.decode())
        username = json_dict.get('username')
        mobile = json_dict.get('mobile')
        password = json_dict.get('password')
        password1 = json_dict.get('password1')
        sms_code = json_dict.get('sms_code')

        # 检验参数
        if not all([username, mobile, password, password1, sms_code]):
            return http.JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': '缺少参数'})
        # 校验手机号
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.JsonResponse({'code': RETCODE.MOBILEERR, 'errmsg': '手机号格式错误'})
        # 校验密码
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.JsonResponse({'code': RETCODE.PWDERR, 'errmsg': '密码格式错误'})
        # 检验两次密码是否一致
        if password != password1:
            return http.JsonResponse({'code': RETCODE.PWDERR, 'errmsg': '两次密码不一致'})
        redis_conn = get_redis_connection('code')
        sms_code_saved = redis_conn.get('sms_%s' % mobile)
        if sms_code_saved is None:
            return render(request, 'register.html', {'sms_code_errmsg': '无效的短信验证码'})
        if sms_code != sms_code_saved.decode():
            return render(request, 'register.html', {'sms_code_errmsg': '输入短信验证码有误'})
        try:

            user = User.objects.create_user(username=username, password=password, mobile=mobile)
        except Exception as e:
            print(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '注册失败'})

        login(request, user)
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '注册成功'})


class LoginView(View):
    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        # 获取参数
        json_dict = json.loads(request.body.decode())
        username = json_dict.get('username')
        password = json_dict.get('password')

        # 校验参数
        if not all([username, password]):
            return http.JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': '缺少必传参数'})
        if not re.match(r'[a-zA-Z0-9_]{5,20}', username):
            return http.JsonResponse({'code': RETCODE.USERERR, 'errmsg': '用户名格式错误'})
        if not re.match(r'[a-zA-Z0-9_]{8,20}', password):
            return http.JsonResponse({'code': RETCODE.PWDERR, 'errmsg': '密码格式错误'})
        user = authenticate(username=username, password=password)
        if not user:
            return http.JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '用户名或密码错误'})
        login(request, user)
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '登录成功'})


class LogoutView(View):
    '退出登录'

    def get(self, request):
        # 清除session
        logout(request)
        # 重定向
        response = redirect(reverse('index:index'))
        # 清除username
        response.delete_cookie('username')
        return response


class UserCenterView(LoginRequiredMixin, View):

    def get(self, request):
        context = {
            'username': request.user.username,
            'mobile': request.user.mobile,
        }
        return render(request, 'uc-account.html', context=context)

    def post(self, request):
        # 获取参数
        json_data = json.loads(request.body.decode())
        username = json_data.get('username')
        print(username)
        # 校验参数
        if not all([username]):
            return http.HttpResponseBadRequest('参数不足')

        user = User.objects.get(id=request.user.id)
        # 保存到数据库
        try:
            user.username = username
            user.save()

        except DatabaseError:
            return render(request, 'uc-account.html', {'register_errmsg': '修改失败'})

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '修改成功'})


class AccountSecurity(View):
    def get(self, request):
        return render(request, 'uc-safe.html')


class PasswordView(View):
    def get(self, request):
        '修改密码页面'
        return render(request, 'uc-verify2.html')

    def post(self, request):
        # 获取参数
        json_data = json.loads(request.body.decode())
        old_password = json_data.get('old_password')
        new_password = json_data.get('new_password')
        # 验证参数
        if not all([old_password, new_password]):
            return http.JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': '缺少必传参数'})
        if not re.match(r'^[0-9A-Za-z]{8,20}$', new_password):
            return http.JsonResponse({'code': RETCODE.PWDERR, 'errmsg': '密码最少8位，最长20位'})

        # 检验旧密码是否正确
        if not request.user.check_password(old_password):
            print(111)
            return render(request, 'uc-verify2.html', {'errmsg': '原始密码错误'})
        # 4.更新新密码
        try:
            request.user.set_password(new_password)
            request.user.save()
        except Exception as e:
            return render(request, 'uc-verify2.html', {'errmsg': '修改密码失败'})
        # 退出登陆,删除登陆信息
        logout(request)

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '修改成功'})


class Mobile(View):
    def get(self, request):
        context = {
            'mobile': request.user.mobile
        }
        return render(request, 'uc-verify.html', context=context)

    def post(self, request):
        # 获取参数
        json_data = json.loads(request.body.decode())
        mobile = json_data.get('mobile')
        sms_code = json_data.get('sms_code')
        # 校验参数
        if not all([mobile, sms_code]):
            return http.JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': '缺少必传参数'})
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.JsonResponse({'code': RETCODE.MOBILEERR, 'errmsg': '手机号格式错误'})
        # 验证码
        redis_conn = get_redis_connection('code')
        sms_code_saved = redis_conn.get('sms_%s' % mobile)
        if sms_code_saved is None:
            return render(request, 'register.html', {'sms_code_errmsg': '无效的短信验证码'})
        if sms_code != sms_code_saved.decode():
            return render(request, 'register.html', {'sms_code_errmsg': '输入短信验证码有误'})
        user = User.objects.get(id=request.user.id)
        # 保存到数据库
        try:
            user.mobile = mobile
            user.save()
        except DatabaseError:
            return render(request, 'uc-account.html', {'register_errmsg': '修改失败'})

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '修改成功'})


class AddressView(View):
    def get(self, request):
        """提供收货地址界面"""
        # 获取用户地址列表
        addresses = Address.objects.filter(user=request.user, is_deleted=False)

        address_dict_list = []
        for address in addresses:
            address_dict = {
                "id": address.id,
                "receiver": address.receiver,
                "province": address.province.name,
                "city": address.city.name,
                "district": address.district.name,
                "place": address.place,
                "mobile": address.mobile,

            }
            address_dict_list.append(address_dict)

        context = {
            'addresses': address_dict_list,
        }

        return render(request, 'address.html', context)